package com.weimob.mcloud.wechatwork.customer.mq.userPermission.handler;

import com.weimob.mcloud.wechatwork.core.base.MultiResponse;
import com.weimob.mcloud.wechatwork.core.entity.privatesphere.PrivateSphere;
import com.weimob.mcloud.wechatwork.core.entity.relation.employee.Employee;
import com.weimob.mcloud.wechatwork.customer.externalDependencyProxy.privateSphere.PrivateSphereServiceProxy;
import com.weimob.mcloud.wechatwork.customer.externalDependencyProxy.usermanagement.EmployeeProxy;
import com.weimob.mcloud.wechatwork.customer.mq.userPermission.dto.EmployeeVidsDTO;
import com.weimob.mcloud.wechatwork.customer.mq.userPermission.dto.PermissionChangeMsgDTO;
import com.weimob.mcloud.wechatwork.customer.mq.userPermission.handler.logicHandler.PermisssionChangeHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.util.*;

/**
 * 处理员工数据隔离权限数据
 *
 * @Author LeoLee
 * @Date 2022/8/22 11:38
 * @Version 1.0
 */
@Slf4j
@Component
public class UserPermissionChangeHandler extends AbstractUserPermissionChangeHandler implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    @Autowired
    private PrivateSphereServiceProxy privateSphereServiceProxy;

    @Autowired
    private EmployeeProxy employeeProxy;


    @Override
    protected List<? extends EmployeeVidsDTO> getAllEmployee(PermissionChangeMsgDTO permissionChangeMsgDTO) {
        if (null == permissionChangeMsgDTO || permissionChangeMsgDTO.getType() == null) {
            return null;
        }
        List<EmployeeVidsDTO> resultList = new ArrayList<>();
        switch (PermissionChangeTypeEnum.getEnumByCode(permissionChangeMsgDTO.getType())) {
            case EMPLOYEE:
                //员工维度消息
                if (CollectionUtils.isNotEmpty(permissionChangeMsgDTO.getEmployeeVidList())) {
                    //直接返回员工和vid的关系
                    resultList.addAll(permissionChangeMsgDTO.getEmployeeVidList());
                }
                break;
            case DEPARTMENT:
                //客户不需要处理部门维度的权限变更
                log.warn("customer server don't include scene[department], ignore");
                break;
            case ALL_VID_CHANGE:
                //corId维度消息
                String corpId = permissionChangeMsgDTO.getCorpId();
                if (StringUtils.isNotEmpty(corpId)) {
                    //根据corpid查询所有员工
                    List<? extends EmployeeVidsDTO> employeeVidsDTOS = pageSearchEmployeeList(corpId);
                    if (CollectionUtils.isNotEmpty(employeeVidsDTOS)) {
                        resultList.addAll(employeeVidsDTOS);
                    }
                }
                break;
            default:
                log.warn("user permission message is disqualification, cause type is undefined, type:[{}]", permissionChangeMsgDTO.getType());
                break;
        }
        return resultList;
    }

    @Override
    protected void updatePermission(List<? extends EmployeeVidsDTO> employeeVidsDTOS, Integer msgType) {
        //获取所有具体的业务处理器，调用各个业务处理器更新vid权限的方法，修改业务数据中的权限
        //PermisssionChangeHandler是标记接口，所有具体的业务处理器需要现实该接口并注册为bean才会被
        //com.weimob.mcloud.wechatwork.customer.mq.userPermission.handler.AbstractUserPermissionChangeHandler.userPermissionChange方法执行
        Map<String, PermisssionChangeHandler> beansOfType = applicationContext.getBeansOfType(PermisssionChangeHandler.class);
        for (PermisssionChangeHandler permisssionChangeHandler : beansOfType.values()) {
            permisssionChangeHandler.updatePermission(employeeVidsDTOS, msgType);
        }
    }


    /**
     * 分页获取corpId所有的员工与vid的关系
     * @Author LeoLee
     * @Date 15:51 2022/8/23
     * @param corpId
     * @return java.util.List<? extends com.weimob.mcloud.wechatwork.customer.mq.userPermission.dto.EmployeeVidsDTO>
     */
    private List<? extends EmployeeVidsDTO> pageSearchEmployeeList(String corpId) {
        //获取私域 数据隔离专用多bos不考虑这个
        PrivateSphere privateSphere = privateSphereServiceProxy.getPrivateSphereRequest(corpId);
        //根据私域分页查询员工信息
        Integer pageSize = 500, pageNum = 1;
        //最大循环次数，防止查询接口totalPage出问题，导致无限循环下去
        Integer maxLoop = 1000;
        List<EmployeeVidsDTO> resultList = new ArrayList<>();
        MultiResponse<Employee> response;
        do {
            response = employeeProxy.fetchEmployee(privateSphere, pageSize, pageNum);
            //获取员工和vid的对应关系
            List<? extends EmployeeVidsDTO> employeeVidsDTOS = parseEmployeeInfoList(response.getDataList(), corpId);
            if (CollectionUtils.isNotEmpty(employeeVidsDTOS)) {
                resultList.addAll(employeeVidsDTOS);
            }
            pageNum++;
        } while (response.getTotalPage() != null && pageNum <= response.getTotalPage() && pageNum <= maxLoop);
        return resultList;
    }

    /**
     * 根据员工信息获取员工与vid的对应关系
     * @Author LeoLee
     * @Date 15:32 2022/8/23
     * @param dataList
     * @return java.util.List<? extends com.weimob.mcloud.wechatwork.customer.mq.userPermission.dto.EmployeeVidsDTO>
     */
    private List<? extends EmployeeVidsDTO> parseEmployeeInfoList(List<Employee> dataList, String corpId) {
        if (CollectionUtils.isEmpty(dataList)) {
            return null;
        }
        List<EmployeeVidsDTO> resultList = new ArrayList<>();
        for (Employee employee : dataList) {
            //使用set合并员工所属vid节点和上级vid节点，防止重复ss
            Set<Long> finalVids = new HashSet<>();
            if (CollectionUtils.isNotEmpty(employee.getVidList())) {
                finalVids.addAll(employee.getVidList());
            }
            if (CollectionUtils.isNotEmpty(employee.getHigherVidList())) {
                finalVids.addAll(employee.getHigherVidList());
            }
            EmployeeVidsDTO employeeVidsDTO = new EmployeeVidsDTO(corpId, employee.getId(), new ArrayList<>(finalVids));
            resultList.add(employeeVidsDTO);
        }
        return resultList;
    }


}
